Repository navigation
chore: sync fork with upstream (#357, #359, #360, #361) - #73
Merged
Merged
Conversation
…hattymin#361) A model with no row in ModelPricing.table renders its cost as "Unavailable" with no other trace, so a newly released model (Opus 5.5, fixed in chattymin#354) was only noticed from a screenshot. Log each unpriced model identity once per process from LocalUsageReader.Bucket.add ("Unpriced model: <id> — its cost shows as Unavailable until ModelPricing.table has a row"). Rows whose source already marks the cost as unavailable are not reported: a missing table row is not the cause there. Tests: the once-per-identity dedupe (normalized like the price lookup), and the wiring observed through that dedupe, since AppLog is a no-op under swift test. Fault injection: removing the report, or reporting source-unavailable rows too, each fails the wiring test. Claude-Session: https://claude.ai/code/session_01PNenigaFnwvcTs2kDND16Z Co-authored-by: turtle hermit <4173875+cte13@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ttymin#360) Status lines that describe an unchanged state are written on every poll: uninstalled providers (phase1 recv ... today=nil), a missing Cursor login (cursor api / cursor limits: no session token), a missing codex binary, unavailable limits, provider status, the Claude desktop scan depth notice. AppLog rotates at 2 MB, so this noise pushes out the history needed to diagnose a crash or a failed sync. In one real log, `cursor api: no session token — state.vscdb: missing` alone appeared 2,658 times in three weeks. Add LogRepeatSuppressor (pure, tested) and AppLog.writeIfChanged, and use it for those 11 status lines. A changed message is written at once, an unchanged one is reaffirmed once an hour, and each provider/state has its own key so one change never lifts another's suppression. Event lines and lines whose values change every tick keep using AppLog.write. Claude-Session: https://claude.ai/code/session_01PNenigaFnwvcTs2kDND16Z Co-authored-by: turtle hermit <4173875+cte13@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…cache (chattymin#359) LocalUsageProvider uses LocalUsageCache.shared, whose default path is the user's real Application Support/PokeTokenBar/usage-cache.json with no gate. Any refresh() that runs the real providers during `swift test` (a store built with default providers, a detached Task that outlives its test) reads and rewrites that file. Measured with the app quit: one full suite run changed the real file's checksum and grew it from 965 KB to 1.02 MB; no other state file changed. Tests cannot catch this by injecting paths: injection covers the test that does it, not the process, so the default-path branch is invisible to them. The gate belongs in the store. AppEnv.persistsToUserLocation owns the rule (an injected path is always live; the default path only in the app bundle) so later stores reuse it instead of copying it. Reads are gated as well as writes, so a test cannot assert on fixtures mixed with the user's data. Verified by fault injection: removing the read gate loads 156 real blobs next to the single fixture; removing the write gate changes the real file's mtime. With the fix, a full run leaves every state file unchanged. Claude-Session: https://claude.ai/code/session_01PNenigaFnwvcTs2kDND16Z Co-authored-by: turtle hermit <4173875+cte13@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ymin#357) The menu bar limit items now use the same color as their popover gauge: the six pace tiers when the window's pace is known (Claude 5-hour, the Codex primary window), the warn/crit threshold colors otherwise (Antigravity, Cursor). Only each "Label NN%" item is colored; separators and the token/cost line keep the system text color. - PaceTier.gauge is the single rule; the popover's quotaRow uses it too, so the two surfaces cannot disagree. - Settings > Menu bar > Percent color (shown with Limit %): Match gauges (default), Only when fast, or Off. - The colors are recomputed on every refresh, so a tier that moves with the clock redraws even when the text stays the same. No new timer.
…in#360, chattymin#361) Merges upstream/main (merge commit, not squash, to keep ancestry): - chattymin#357 feat(menubar): color limit percentages like the popover gauges - chattymin#359 fix: stop the test suite from reading and rewriting the user's usage cache - chattymin#360 fix: stop unchanged status lines from filling the log every poll - chattymin#361 fix: log each unpriced model once so a missing price row is noticed chattymin#359/chattymin#360 are the upstreamed forms of the fork's #22/#29, so conflicts were the same code with reworded (English) comments; upstream's side was taken. Fork-only changes kept: - Antigravity manual-refresh failure message (UsageStore catch block) - OpenCode Go menu bar item, ported to chattymin#357's MenuLimitPart via add() - dropped the fork's duplicate persistsToDisk assignment that auto-merge kept next to upstream's Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PNenigaFnwvcTs2kDND16Z
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings in 4 upstream PRs:
Conflict resolution
chattymin#359 and chattymin#360 are the upstreamed forms of the fork's own #22 and #29, so nearly all 9 conflicted files were the same code with reworded (now English) comments. Upstream's side was taken in those files. Test sets were compared first:
LogRepeatSuppressorTestshas the same 6 tests on both sides, so no fork-only test was dropped.Fork-only behavior kept:
UsageStorecatch block): the fork-onlyantigravityLimitRefreshFailure, which upstream doesn't have.menuLimitPartsfrom strings toMenuLimitPart. The fork-only OpenCode entry now goes through the sameadd()helper, so it gets gauge colors too (no pace marker, like the Antigravity and Cursor items).persistsToDiskassignment: auto-merge kept the fork's copy next to upstream's, and the compiler rejected it. The fork's copy was dropped. Every file touched by both sides was then scanned for other statements duplicated by the merge; none were found.Test plan
swift buildswift test: 1,556 tests, 2 failures. Both are the knownPhoneLimitStatusBuilderTestsfailures already onmain, fixed by fix(limit-history): stop dimming resets watched at slow refresh intervals #72.🤖 Generated with Claude Code
https://claude.ai/code/session_01PNenigaFnwvcTs2kDND16Z